#include <iostream>

using std::cout;
using std::endl;

//宏定义发生的时机在预处理阶段,进行字符串的替换,如果出现了bug
//可能需要等到运行的时候才知道
#define MAX 100

#define multiply(x, y)  x * y

void test()
{
    int a;
    //const常量发生的时机在编译的时候，如果发生了bug，那么在
    //编译的时候就会发现
    //
    //内置类型(为了与后面面向对象中的自定义类型区分的)
    //char/short/int/float/double/long/bool
    //
    //const修饰的变量称为常量,常量在定义的时候必须要进行初始化
    const int number = 10;
    cout << "number = " << number << endl;

    //dnG,d删除的意思，n目的行号
    //注释多行可以使用ngcc
    //dt)  = d删除   t = to   )
    /* number = 20;//error,常量不能进行赋值,为了保护常量不被修改 */
    /* cout << "number = " << number << endl; */

    int b = 1, c = 2, d = 3, x = 4;
    cout << "multiply(b + c, d + x) = " 
         << multiply(b + c, d + x) << endl;
}

//两组重要的概念
//数组指针              指针数组/int类型的数组int pArray[]
//int (*pArray)[]       int* pArray[]

//函数指针              指针函数
//int (*pf)(int)        int*  pf(int)

/* int pf(int ) */
/* { */

/* } */

void test2()
{
    int number = 10;
    int *p = &number;
    //指针所指变量的值，指针的指向
    /* number = 200; */
    *p = 200;
    cout << "*p = " << *p << endl;
    cout << "number = " << number << endl;

    int a = 300;
    p = &a;
    p = NULL;//C   (void *)0, C++ 0
    p = nullptr;//C++11，空指针的一个用法,C++，nullptr,(void *)0

    cout << endl << endl;
    int value = 1;
    //1、当const位于*左边的时候，称为常量指针
    const int *p1 = &value;
    /* *p1 = 10;//error,不能改变指针所指的变量的值 */
    p1 = &number;//ok,可以改变指针本身（指向）

    cout << endl << endl;
    int value2 = 20;
    //2、当const位于*左边的时候，称为常量指针
    int const *p2 = &value2;
    /* *p2 = 10;//error,不能改变指针所指的变量的值 */
    p2 = &number;//ok,可以改变指针本身（指向）

    cout << endl << endl;
    int value3 = 300;
    //3、当const位于*右边的时候，称为指针常量
    int * const p3 = &value3;
    *p3 = 10;//ok,可以改变指针所指的变量的值
    /* p3 = &number;//error,不可以改变指针本身（指向） */

    cout << endl << endl;
    int value4 = 400;
    //4、双const
    const int * const p4 = &value4;
    /* *p4 = 10;//error,不可以改变指针所指的变量的值 */
    /* p4 = &number;//error,不可以改变指针本身（指向） */
}

int main(int argc, char **argv)
{
    test2();
    return 0;
}

